package com.huzz.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huzz.entity.SysDict;
import com.huzz.entity.SysDictItem;
import com.huzz.mapper.SysDictItemMapper;
import com.huzz.mapper.SysDictMapper;
import com.huzz.model.SysDictCreateModel;
import com.huzz.model.SysDictQueryModel;
import com.huzz.model.SysDictUpdateModel;
import com.huzz.service.ISysDictService;
import com.huzz.util.entityutil.FieldUtil;
import com.huzz.util.entityutil.ModelUtil;
import com.huzz.vo.SysDictVO;
import com.huzz.util.body.DataBox;
import com.huzz.util.body.ResultCode;
import com.huzz.util.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
* 系统字典-业务实现层
*
* @author 童年的纸飞机
* @since 2023-06-07 13:37
*/
@Service
@Slf4j
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements ISysDictService {

    /**
     * 系统字典Mapper
     */
    @Autowired
    private SysDictMapper sysDictMapper;

    /**
     * 系统字典ItemMapper
     */
    @Autowired
    private SysDictItemMapper sysDictItemMapper;

    /**
     * 根据进行ID查询SysDict
     * @param id
     * @return
     */
    @Override
    public SysDict getSysDictById(Integer id) {
        return sysDictMapper.selectById(id);
    }

    /**
     * 新增SysDict
     * @param model
     * @return
     */
    @Override
    @Transactional
    public boolean createSysDict(SysDictCreateModel model) {

        SysDict sysDict = ModelUtil.transToSimilarEntity(model, SysDict.class);
        FieldUtil.setCreatedAndUpdateField(sysDict);


        return sysDictMapper.insert(sysDict) > 0;
    }

    /**
     * 更新SysDict
     * @param model
     * @return
     */
    @Override
    @Transactional
    public boolean updateSysDict(SysDictUpdateModel model) {
        if (sysDictMapper.selectById(model.getId()) == null) {
            throw new BizException(ResultCode.COMMON_FAIL.getCode(), "更新对象不存在");
        }

        SysDict sysDict = ModelUtil.transToSimilarEntity(model, SysDict.class);
        FieldUtil.setUpdateField(sysDict);

        return sysDictMapper.updateById(sysDict) > 0;
    }

    /**
     * 根据ID进行删除SysDict
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean deleteSysDictById(Integer id) {
        if (sysDictMapper.selectById(id) == null) {
            throw new BizException(ResultCode.COMMON_FAIL.getCode(), "删除对象不存在");
        }
        // 删除字典数据
        sysDictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().eq(SysDictItem::getDictId, id));

        return sysDictMapper.deleteById(id) > 0;
    }

    /**
     * 分页查询SysDict列表
     * @param pageNum
     * @param pageSize
     * @param model
     * @return
     */
    @Override
    public IPage<SysDictVO> selectSysDictPage(Integer pageNum, Integer pageSize, SysDictQueryModel model) {
        QueryWrapper<SysDict> wrapper = getQueryWrapper(model);

        return sysDictMapper.selectSysDictVOList(new Page<>(pageNum, pageSize), wrapper);
    }

    /**
     * 查询SysDict列表
     * @param model
     * @return
     */
    @Override
    public List<SysDict> selectSysDictList(SysDictQueryModel model) {
        QueryWrapper<SysDict> wrapper = getQueryWrapper(model);

        return sysDictMapper.selectList(wrapper);
    }

    /**
     * 导出SysDict列表
     * @param request
     * @param response
     * @param model
     * @return
     */
    @Override
    public void exportSysDictExcel(HttpServletRequest request, HttpServletResponse response, SysDictQueryModel model) {
        QueryWrapper<SysDict> wrapper = getQueryWrapper(model);

        List<SysDictVO> data = sysDictMapper.selectSysDictVOList(wrapper);

        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("系统字典列表", "SysDictVO"), SysDictVO.class, data);
        String fileName = String.format("系统字典_%d.xls", System.currentTimeMillis());
        response.setHeader("Content-Disposition", "attachment;Filename=" + fileName);
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        try {
            response.flushBuffer();
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 批量编辑SysDict
     *
     * @param modelList
     * @return
     */
    @Override
    public DataBox<String> updateSysDictByList(List<SysDictUpdateModel> modelList) {
        List<SysDict> sysDictList = ModelUtil.transToSimilarList(modelList, SysDict.class);
        int i = 0;
        for (SysDict sysDict : sysDictList) {
            FieldUtil.setUpdateField(sysDict);
            i += sysDictMapper.updateById(sysDict);
        }

        return i > 0 ?
        DataBox.succeedBuilder("共" + i + "条记录更新成功, " + (sysDictList.size() - i) + "条记录更新失败") : DataBox.failedBuilder("更新失败");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public DataBox<String> deleteSysDictByIds(List<Integer> ids) {
        int i = sysDictMapper.deleteBatchIds(ids);
        // 清空字典数据
        sysDictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId));

        return i > 0 ?
                DataBox.succeedBuilder("共" + i + "条记录被删除, " + (ids.size() - i) + "条记录删除失败") : DataBox.failedBuilder("删除失败");
    }

    /**
     * 查询条件
     * @param model
     * @return
     */
    private QueryWrapper<SysDict> getQueryWrapper(SysDictQueryModel model) {
        QueryWrapper<SysDict> wrapper = new QueryWrapper<>();

        // 根据 ids 进行查询
        if (model.getIds() != null && model.getIds().length > 0) {
            wrapper.lambda().in(SysDict::getId, model.getIds());
        }
        // 根据 更新时间区间 进行查询
        if (model.getTimeInterval() != null && model.getTimeInterval().length == 2) {
            wrapper.lambda().between(SysDict::getUpdateTime, model.getTimeInterval()[0], model.getTimeInterval()[1]);
        }
        // 根据 字典名称 进行查询
        if (!StringUtils.isEmpty(model.getDictName())) {
            wrapper.lambda().like(SysDict::getDictName, model.getDictName());
        }
        // 根据 状态(1开启,0关闭) 进行查询
        if (null != model.getStatus()) {
            wrapper.lambda().eq(SysDict::getStatus, model.getStatus());
        }
        // 根据 更新时间 进行降序
        wrapper.lambda().orderByDesc(SysDict::getUpdateTime);

        return wrapper;
    }

}